﻿using System;
using System.Collections.Generic;
using Allegro.Framework;

//using System.Linq;
//using System.Text;

namespace Allegro.Mathlib
{
 
    /// <summary>
    /// Set of equations
    /// </summary>
    public interface IEquationSet
    {
        /// <summary>
        /// Name of the equation set
        /// </summary>
        string Name{ get;}

        /// <summary>
        /// Perform mapping of additional variables required by the equation set.
        /// </summary>
        /// <param name="taskMap"></param>
        void MapVariables(IODEIntegrationContext context, ITaskMap taskMap);

        /// <summary>
        /// The binding is completed. Each variable index should be recorded in the equation set. 
        /// </summary>
        /// <param name="taskMap"></param>
        void BindVariables(IODEIntegrationContext context, ITaskMap taskMap);

        /// <summary>
        /// The equationset must add the variables it needs from the context
        /// </summary>
        /// <param name="neededVariableIds"></param>
        void ListNeededVariables(List<string> neededVariableIds);

        /// <summary>
        /// Initialize the equations for execution (called initially before any steps are taken).
        /// Returns true if the equationset was initialized properly, false otherwise
        /// </summary>
        /// <param name="context"></param>
        bool Initialize(IODEIntegrationContext context, ITaskData parameters, ITaskData taskInput);

        /// <summary>
        /// Called prior to taking an integration step. Return true if the computation should proceed.
        /// If this method returns false, the step will not be taken, and the computation stops
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        bool PreStep(IODEIntegrationContext context);

        /// <summary>
        /// Compute derivatives
        /// </summary>
        /// <param name="context"></param>
        /// <param name="dydx"></param>
        /// <param name="completed"></param>
        void DyDx(IODEIntegrationContext context, ref double[] dydx, ref bool[] completed);

        /// <summary>
        /// Compute values directly. 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="yOut"></param>
        /// <param name="integrated"></param>
        /// <param name="completed"></param>
        void ComputeValues(IODEIntegrationContext context, ref double[] yOut, bool[] integrated, ref bool[] completed);

        /// <summary>
        /// Called after taking an integration step. Return true if the computation should proceed.
        /// If this method returns false, the computation stops without taking any more steps
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        bool PostStep(IODEIntegrationContext context);

        /// <summary>
        /// The equationset must add the variables it may compute
        /// </summary>
        /// <param name="computedVariableIds"></param>
        //void ListComputedVariables(List<string> computedVariableIds);

         
    }
}
